﻿#pragma once
#include <QMap>
#include <QMutex>
#include <thread>
#include <mutex>
#include <condition_variable>

#include "../robot/robot.h"
#include "../../pathbuild/path_data.h"

class Pipeline;

struct PathBuffInfo {
	QString execpipe;
	QString execpath;
	QString waitpipe;
	QString waitpath;
};

struct ExecPathList {
	QMap<int, QString> paths;
	int currpoint;
};

class PathExcuteQueue : public QObject
{
	Q_OBJECT
public:
	PathExcuteQueue(QObject* parent);
	~PathExcuteQueue();

	bool Init();

	PathBuffInfo GetPathBuffInfo();
	ExecPathList GetExecPathList();
	/****************************************************************************
	 * 功能: 路径现场启动和关闭
	 * 传参:
	 * 返回值: 成功失败
	 ****************************************************************************/
	bool PathStop();
	bool PathStart();
	/****************************************************************************
	 * 功能: 路径继续执行
	 * 传参: 
	 * 返回值: 成功失败
	 ****************************************************************************/
	bool PathContinueExcute();

	/****************************************************************************
	 * 功能: 路径重新开始
	 * 传参:
	 * 返回值: 成功失败
	 ****************************************************************************/
	bool PathReStartExcute();

	/****************************************************************************
	 * 功能: 判断路径执行队列是否可以添加路径
	 * 传参: 
	 * 返回值: true:表可以继续添加路径，false:不可以
	 ****************************************************************************/
	bool IfPathQueueIsIdle();

	/****************************************************************************
	 * 功能: 添加路径到队列
	 * 传参: pipe: 路径的归属业务线指针，path: 路径数据
	 * 返回值: 0：添加成功， -1：参数异常，-99表示添加失败（队列已满）
	 ****************************************************************************/
	int AddPathToQueue(Pipeline* pipe, const QString& path);

private:
	/*路径执行等待函数*/
	bool WaitForPathFinished();
	/*路径动作执行函数*/
	bool PathActionExcute(int id);
	/*路径点回调函数*/
	int PointIdCallback(const QByteArray& data);

	/*执行buff对应函数*/
	void PathExcuting();	// 路径执行线程
	bool AddPathToExecBuff();	// 添加路径到执行buff
	bool ExecBuffGetPath();		// 执行buff获取路径
	void SetPathExcuteEvent(const QString& str = {});

	/*WaitBuff 对应函数*/
	bool AddPathToWaitBuff(const PathJ& path, Pipeline* pipe);
	bool GetPathFromWaitBuffToExec();
	void SetPathParseEvent();
	/*CacheBuff对应函数*/
	//bool AddPathToCacheBuff(const PathJ& path, Pipeline* pipe);
	//bool GetPathFormCacheBuff();

	bool CheckMoveJLInfo(const MoveJLInfo& info);

	//void ClearCacheBuff();
	void ClearWaitBuff();
	void ClearExecBuff();
signals:
	void PathExcutedFailed(const QString& err);
	void PathParseFailed(const QString& err);

private:
	Robot* m_rob = nullptr;


	//struct CacheBuff {
	//	bool valied;	// 数据是否有效
	//	Pipeline* obj;
	//	QString	pathName;
	//	QList<PointInfoJ> path;
	//} m_cache = {};

	struct ExecBuff {
		bool valied;
		Pipeline* obj;
		QString pathName;
		QList<MoveJLInfo> path;
		QMap<int, MoveJLInfo> movePath;
		QMap<int, ActionInfo> action;
	} m_wait = {};

	ExecBuff m_exec = {};

	QMutex m_buffLock;	// 2个buff共用的读写锁

	bool m_stopFlag = true;	// 线程停止标志未

	QMutex pointIdQueueLock;	// 运行点队列锁
	QList<int> m_pointIdQueue;	// 运行点队列

	std::mutex excuteLock;		// 执行线程锁
	std::condition_variable execCond;	// 执行线程条件变量
	std::thread* m_execThread = nullptr;
};
